<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>Title</title>
    <script src="./vue.js"></script>
    <script src="./index.js"></script>
    <link href="./index.css" rel="stylesheet">
    <link href="./export-template.css" rel="stylesheet">
    <style>
        [v-cloak] {
            display: none;
        }

        .el-radio-group {
            width: 100%;
        }

        .el-radio-button {
            width: 50%;
        }

        .el-radio-button__inner {
            width: 100%;
        }

        .bz {
            width: auto;
            margin-left: 2px;
            vertical-align: text-bottom;
        }
    </style>
</head>
<body>
<script>
    let data = {
        "medicalCalculatorData": [
            {
                "calculateData": {
                    "formulaExpressionItems": [
                        {
                            "item_expression": "(a+b+c)-(d+e+f)"
                        }
                    ],
                    "formulaItems": [
                        {
                            "item_id": "a",
                            "item_name": "掌指关节屈曲度"
                        },
                        {
                            "item_id": "b",
                            "item_name": "近位指间关节屈曲度"
                        },
                        {
                            "item_id": "f",
                            "item_name": "远位指间关节伸直受限度"
                        },
                        {
                            "item_id": "d",
                            "item_name": "掌指关节伸直受限度"
                        },
                        {
                            "item_id": "e",
                            "item_name": "近位指间关节伸直受限度"
                        },
                        {
                            "item_id": "c",
                            "item_name": "远位指间关节屈曲度"
                        }
                    ]
                },
                "sections": []
            }
        ],
        "calculatorSore": [
            {
                "scoreData": [],
                "sections": []
            }
        ],
        "describeContent": "<p>掌指关节（MP），近位指间关节（PIP），远位指间关节（DIP）主动屈曲度之和，减去各关节主动伸直受限度之和，即为该手指总主动活动度（TAM）。各关节伸直以0°为准，过伸部分不计。 TAM＝（MP＋PIP＋DIP）－（MP＋PIP＋DIP） 即，总主动活动度＝各关节屈曲度之和－各关节伸直受限度之和</p>",
        "fields": [
            {
                "kind": 0,
                "ident": 0,
                "name": "公式名称",
                "property": "中华医学会手外科学会手部肌腱修复后评定标准"
            },
            {
                "field_id": "0001AA100000000AAER9",
                "kind": 1,
                "ident": 0,
                "name": "学科分类",
                "property": "[[\"0001AA100000000EJ3TH\"]]",
                "tagId": []
            },
            {
                "kind": 2,
                "ident": 0,
                "name": "关联平台",
                "property": "[\"0001AA100000000JAC55\"]"
            },
            {
                "kind": 3,
                "ident": 0,
                "name": "结果说明",
                "property": "<p>2000年3月，中华医学会手外科学会借鉴国内外各种评价测量方法，制定出了适合我国国情的一系列手外科疾病疗效评价标准，即中华医学会手外科学会上肢部分功能评定试用标准（全国上肢功能评定标准专题研讨会制定，无锡市）。对断指再植、肌腱、神经损伤、手指再造等特定损伤手术治疗以后的功能评定具有指导意义。该评分意义如下：优 活动范围正常。良 TAM＞健侧的75%。 可 TAM＞健侧的50%。差 TAM＜健侧的50%。</p>"
            },
            {
                "kind": 4,
                "ident": 0,
                "name": "参考文献"
            },
            {
                "kind": 5,
                "ident": 0,
                "name": "公式类型"
            }
        ],
        "type": 1,
        "formulaName": "",
        "resultDescription": "",
        "reference": "",
        "webFlag": false,
        "name": '',
        "formulaExplain": ''
    }
</script>
<script>
    if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
        data.webFlag = false
    } else {
        data.webFlag = true
    }
    if (data.type == 3) {
        data.activePanel = 'describe';
    } else {
        data.activePanel = 'calculate';
    }
    data.resultFontColor = '';
    data.calculateResult = 0;
    data.calculateResultDisplay = false;
    data.resultExplanation = '';
    data.selectedFormulaExpressionIdx = 0;

    for (let field of data.fields) {
        if (field.name == '公式名称') {
            data.formulaName = field.property
        } else if (field.name == '结果说明') {
            data.resultDescription = field.property
        } else if (field.name == '参考文献') {
            data.reference = field.property
        } else if (field.name == '又称') {
            data.name = JSON.parse(field.property).map(item => item).join(";");
        } else if (field.name == '公式说明') {
            data.formulaExplain = field.property
        }
    }

    if (!data.formulaName) {
        data.formulaName = '';
    }
    if (!data.describeContent) {
        data.describeContent = '无';
    }
    if (!data.resultDescription) {
        data.resultDescription = '无';
    }
    if (!data.reference) {
        data.reference = '无';
    }
    for (let item of data.calculatorSore) {
        if (item.scoreData) {
            for (let question of item.scoreData) {
                if (question.multiple) {
                    question.checkList = [];
                } else {
                    question.checkId = '';
                }
            }
        }
    }
</script>
<div id="app">
    <el-row class="top-title-cls">
        <div class="label" v-cloak v-html="formulaName"></div>
    </el-row>
    <el-row class="top-title-cls" v-if="name">
        <div class="nick_name_block_cls">
            <div style="display: inline-block;margin-left: 10px">又称:
            </div>
            <div style="margin-left: 5px;display: inline-block" v-html="name">
            </div>
        </div>
    </el-row>
    <el-row v-if="formulaExplain">
        <div style="margin-left: 5px;margin-top:5px;color: red">
            <div style="margin-left: 5px;display: inline-block">*</div>
            <div style="display: inline-block" v-html="formulaExplain"></div>
        </div>
    </el-row>
    <el-radio-group fill="#2DB7A0" v-if="!webFlag && type != 3" v-model="activePanel">
        <el-radio-button label="calculate">计算</el-radio-button>
        <el-radio-button label="describe">说明</el-radio-button>
    </el-radio-group>

    <div class="calculate-cls" v-if="webFlag || activePanel == 'calculate'">


        <!-- 计算型 -->
        <el-row class="formula-calc-block" v-if="type == 1">
            <div>
                <div class="cal-tip"></div>
                <div class="cal-text-cls">
                    公式计算
                </div>
            </div>
            <div style="margin: 15px" v-if="medicalCalculatorData.length > 1" v-cloak>
                <div>请选择:</div>
                <el-radio v-for="(item, idx) in medicalCalculatorData" :key="idx" v-model="selectedFormulaExpressionIdx"
                          :label="idx" style="margin: 10px; ">
                    <span v-html="item.explain"></span>
                </el-radio>
            </div>
            <!-- 列项 -->
            <div v-for="(mcdItem, idx) in medicalCalculatorData" :key="idx" :label="idx" v-cloak>
                <div v-if="idx == selectedFormulaExpressionIdx">

                    <div :key="item.item_id" class="lx-text-cls"
                         v-for="(item, idx) in mcdItem.calculateData.formulaItems">
                        <div>
                            <span v-if="mcdItem.calculateData.formulaItems.length>1">{{ idx + 1 }}.</span>
                            <span v-html="item.item_name" v-if="item.item_name"></span>
                            <span v-html="'(' + item.item_unit + ')'" v-if="item.item_unit"></span>
                        </div>
                        <el-input-number :controls="false" style="margin: 10px;"
                                         v-model="item.item_value"></el-input-number>
                    </div>

                </div>
            </div>
        </el-row>

        <!-- 评分型 -->
        <el-row class="score-calc-block" v-else-if="type == 2">
            <div>
                <div class="score-tip"></div>
                <div class="score-text-cls">评分计算</div>
            </div>

            <div style="margin: 15px" v-if="calculatorSore.length > 1" v-cloak>
                <div>请选择:</div>
                <el-radio v-for="(item, idx) in calculatorSore" :key="idx" v-model="selectedFormulaExpressionIdx"
                          :label="idx" style="margin: 10px; ">
                    <span v-html="item.explain"/>
                </el-radio>
            </div>

            <div v-for="(mcdItem, idx) in calculatorSore" :key="idx" :label="idx" v-cloak>
                <div class="score-calc-content" v-if="idx == selectedFormulaExpressionIdx">

                    <div :key="questionItem.id" class="score-lx-text-cls"
                         v-for="(questionItem, idx) in mcdItem.scoreData">
                        <span v-if="mcdItem.scoreData.length>1">{{ (idx + 1) }}.</span>
                        <span class="score-title-cls"
                              v-html="questionItem.name + (questionItem.multiple ? '(多选)' : '(单选)')"></span>
                        <div class="score-options-cls" v-if="!questionItem.multiple">
                            <el-radio-group v-model="questionItem.checkId">
                                <el-radio v-for="(optionItem, optionIdx) in questionItem.items"
                                          :key="optionIdx"
                                          :label="optionItem.id.toString()"
                                          style="display: flex; margin: 10px;word-break: break-all;white-space: normal;">
                                    <span v-html="optionItem.describe"></span>
                                </el-radio>
                            </el-radio-group>
                        </div>
                        <div class="score-options-cls" v-else>
                            <el-checkbox-group v-model="questionItem.checkList">
                                <el-checkbox v-for="(optionItem, optionIdx) in questionItem.items"
                                             :key="optionIdx"
                                             :label="optionItem.id"
                                             style="display: flex; margin: 10px;word-break: break-all;white-space: normal;">
                                    <span v-html="optionItem.describe"></span>
                                </el-checkbox>
                            </el-checkbox-group>
                        </div>
                    </div>
                </div>
            </div>

        </el-row>

        <el-row class="calc-result-block" v-if="type != 3">
            <div>
                <div class="cal-result-tip"></div>
                <div class="cal-result-text-cls">
                    计算结果
                </div>
            </div>
            <div class="recalculate-block-cls" v-cloak>
                <div class="calculate-result-cls" v-if="calculateResultDisplay">
                    <span v-html="calculateResult"/>
                    <span v-if="type == 1"
                          v-html="medicalCalculatorData[selectedFormulaExpressionIdx].calculateData.resultUnit"></span>
                    <span :style="{'color': resultFontColor}" v-html="'('+resultExplanation+')'"
                          v-if="resultFontColor"></span>
                </div>
                <div class="recalculate-cls">
                    <el-button class="cal-btn-class" @click="calculate">
                        {{ calculateResultDisplay ? '重新计算' : '点击计算' }}
                    </el-button>
                </div>
                <div class="warning-text-cls">
                    *所有计算结果必须重新核对，且不能作为临床决策的唯一依据
                </div>
            </div>
        </el-row>
    </div>

    <div class="describe-cls" v-if="webFlag || activePanel == 'describe'">
        <el-row class="describeContent-block">
            <div class="desc-tip"></div>
            <div class="desc-text-cls" v-html="type === 3 ? '描述' : '计算方法'">
            </div>
            <div class="describeContent-content" id="describeContentDiv" v-html="describeContent">
            </div>
        </el-row>

        <el-row class="resultDescription-block">
            <div>
                <div class="result-desc-tip"></div>
                <div class="result-desc-text-cls">
                    结果说明
                </div>
            </div>
            <div class="resultDescription-content" v-html="resultDescription">
            </div>
        </el-row>

        <el-row class="reference-block">
            <div>
                <div class="reference-tip"></div>
                <div class="reference-text-cls">
                    参考文献
                </div>
            </div>
            <div class="reference-content" style="white-space: pre-wrap;" v-cloak v-html="reference"></div>
        </el-row>
    </div>


</div>
<script>
    let resultColorMap = {
        default: 'gray',
        normal: 'green',
        excess: 'orange',
        serious: 'red'
    }
    let app = new Vue({
        el: '#app',
        methods: {
            calculate() {
                this.resultFontColor = ''
                this.calculateResult = 0
                this.resultExplanation = 0
                try {
                    // 公式类型计算得分;
                    if (this.type == 1) {
                        let cntExpression = ' ' + this.medicalCalculatorData[this.selectedFormulaExpressionIdx].calculateData.formulaExpressionItems[0].item_expression + ' ';
                        for (let cntItem of this.medicalCalculatorData[this.selectedFormulaExpressionIdx].calculateData.formulaItems) {
                            let reg = new RegExp(`[^a-zA-Z]${cntItem.item_id}[^a-zA-Z]`);
                            while (reg.test(cntExpression)) {
                                let strOri = cntExpression.match(reg)[0];
                                // 把所有字符都默认为1, eval计算 (1/0)结果为Infinity, 不会抛异常;
                                let strNew = strOri.replace(cntItem.item_id, `(${cntItem.item_value})`);
                                cntExpression = cntExpression.replace(strOri, strNew);
                            }
                        }
                        // eval 计算, 如果表达式有误, 则抛异常;
                        this.calculateResult = eval(cntExpression);
                        // 保留两位有效数字;
                        this.calculateResult = Math.round(this.calculateResult * 100) / 100;
                        // 与结果集比较;
                        this.compareWithResultItems(this.calculateResult, this.medicalCalculatorData[this.selectedFormulaExpressionIdx].sections);
                    }
                    // 评分类型计算得分;
                    else if (this.type == 2) {
                        for (let question of this.calculatorSore[this.selectedFormulaExpressionIdx].scoreData) {
                            for (let item of question.items) {
                                if (question.multiple) {
                                    if (question.checkList.indexOf(item.id) != -1) {
                                        this.calculateResult += parseFloat(item.score);
                                    }
                                } else if (question.checkId == item.id) {
                                    this.calculateResult += parseFloat(item.score);
                                }
                            }
                        }
                        // 保留两位有效数字;
                        this.calculateResult = Math.round(this.calculateResult * 100) / 100;
                        // 与结果集比较;
                        this.compareWithResultItems(this.calculateResult, this.calculatorSore[this.selectedFormulaExpressionIdx].sections);
                    }
                    if (window.isNaN(this.calculateResult)) {
                        throw '结果有误'
                    }
                    this.calculateResultDisplay = true
                } catch (e) {
                    this.calculateResultDisplay = false
                    alert('计算失败');
                }
            },
            compareWithResultItems(result, resultItems) {
                // 结果与结果集比较
                let relationArray = ['&&', '||'];
                let conditionArray = ['>=', '>', '==', '<=', '<'];
                for (let resultItem of resultItems) {
                    let resultExpression = 'true';
                    for (let condition of resultItem.sections) {
                        resultExpression += relationArray[condition.relation] + '(' + this.calculateResult + ')' + conditionArray[condition.condition] + '(' + condition.value + ')';
                    }
                    let cntResultFlag = eval(resultExpression);
                    if (cntResultFlag) {
                        this.resultFontColor = resultColorMap[resultItem.result];
                        this.resultExplanation = resultItem.explanation;
                        return;
                    }
                }
            }
        },
        watch: {
            scoreData: {
                handler(nv) {
                    for (let question of nv) {
                        if (question.multiple && !question.checkList) {
                            this.$set(question, 'checkList', []);
                        }
                    }
                },
                deep: true
            },
        },
        data
    })
    // 生僻字, 行内图, 高度自适应, 与兄弟节点文字在垂直方向下对齐
    var fontSize = getComputedStyle(document.documentElement).fontSize;
    Array.from(document.getElementsByClassName('bz')).forEach(function (item) {
        item.style.height = fontSize;
    })
</script>
</body>
</html>
